package com.example.gulimall.common.filter;

import com.example.gulimall.common.utils.ObjectMapperKit;
import com.example.gulimall.common.utils.WrappedHttpServletRequest;
import lombok.extern.slf4j.Slf4j;
import org.springframework.http.MediaType;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.AuthenticationException;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;

/**
 * <p>@description: 用户名密码过滤器  </p>
 * <p>@author: JGD </p>
 * <p>@create: 2020/3/17 14:40 </p>
 * <p>@version : 2.0.0
 **/
@Slf4j
public class BaseUsernamePasswordAuthenticateFilter extends UsernamePasswordAuthenticationFilter {

    @Override
    public Authentication attemptAuthentication(HttpServletRequest request, HttpServletResponse response) throws AuthenticationException {
        WrappedHttpServletRequest requestWrapper = new WrappedHttpServletRequest(request);
        //当请求为application/json时，采用流的方式获取请求参数
        if (requestWrapper.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_UTF8_VALUE)
                || requestWrapper.getContentType().equalsIgnoreCase(MediaType.APPLICATION_JSON_VALUE)) {

            UsernamePasswordAuthenticationToken authRequest = null;
            try (InputStream is = requestWrapper.getInputStream()) {
                HashMap params = ObjectMapperKit.toObject(is, HashMap.class);
                authRequest = new UsernamePasswordAuthenticationToken(params.get("username"), params.get("password"));
                return this.getAuthenticationManager().authenticate(authRequest);
            } catch (IOException e) {
                log.debug("序列化请求参数失败", e);
                authRequest = new UsernamePasswordAuthenticationToken("", "");
                return this.getAuthenticationManager().authenticate(authRequest);
            } finally {
                assert authRequest != null;
                setDetails(requestWrapper, authRequest);
            }
        } else {
            return super.attemptAuthentication(request, response);
        }
    }
}
